/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.impl;

import picounit.Interface;
import picounit.features.registry.DefaultTypeFactory;
import picounit.features.registry.Entry;
import picounit.features.registry.TypeFactory;
import previous.picounit.TestCase;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class DefaultTypeFactoryTest extends TestCase {
	private final Entry<String, String> stringEntry = injectCollaborator();

	public void willNotHaveAnyInstancesWhenNotGivenAnyEntries() {
		verify.that(typeFactory(withNoEntries()).hasInstance(String.class))
			.isFalse();
	}

	public void willHaveAnInstanceWhenGivenAnEntry() {
		should.call(stringEntry.matches(String.class))
			.andReturn(true).atLeastOnce();

		should.call(stringEntry.get())
			.andReturn("value");

		should.expectAboveWhenTheFollowingOccurs();

		TypeFactory typeFactory = typeFactory(with(stringEntry));

		boolean hasStringInstance = typeFactory.hasInstance(String.class);
		
		String stringInstance = typeFactory.getInstance(String.class);

		verify.that(hasStringInstance)
			.isTrue();

		verify.that(stringInstance)
			.isEqualTo("value");
	}

	public void willNotHaveAnyInstancesOfOneClassWhenGivenEntriesForAnotherClass() {
		should.call(stringEntry.matches(Interface.class))
			.andReturn(false);

		should.expectAboveWhenTheFollowingOccurs();

		verify.that(typeFactory(with(stringEntry)).hasInstance(Interface.class))
			.isFalse();
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	private TypeFactory typeFactory(List<Entry<?, ?>> entries) {
		return new DefaultTypeFactory().addEntries(entries);
	}

	private List<Entry<?, ?>> withNoEntries() {
		return Collections.emptyList();
	}

	private List<Entry<?, ?>> with(Entry<?, ?> ... entries) {
		return Arrays.asList(entries);
	}
}
